﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using KeyCore.Domain.Model;
using KeyCore.Framework.Contexts;

namespace KeyCore.Framework.DbInit
{
    public class KeyCoreDbContext : BaseContext<KeyCoreDbContext>
    {
        public KeyCoreDbContext()
        {
            Database.SetInitializer(new DbCreatenIitializer());
        }

        public DbSet<User> Users { get; set; }
        public DbSet<UserRoles> UserRoles { get; set; }
        public DbSet<LoansClient> LoansClients { get; set; }
        public DbSet<AdresTyp> AdresTyp { get; set; }
        public DbSet<Wojewodztwo> Wojewodztwo { get; set; }
        public DbSet<Kraj> Kraj { get; set; }
        public DbSet<TypDokumentu> TypDokumentu { get; set; }
        public DbSet<Rodzice> Rodzice { get; set; }
        public DbSet<Osoba> Osoba { get; set; }
        public DbSet<Miejscowosc> Miejscowosc { get; set; }
        public DbSet<DokumentTozsamosci> DokumentTozsamosci { get; set; }
        public DbSet<DaneOsobowe> DaneOsobowe { get; set; }
        public DbSet<Adres> Adres { get; set; }
        public DbSet<Bank> Bank { get; set; }
        public DbSet<KontoBankowe> KontoBankowe { get; set; }
        public DbSet<TelefonTyp> TelefonTyp { get; set; }
        public DbSet<TelefonPrefix> TelefonPrefix { get; set; }
        public DbSet<Telefon> Telefon { get; set; }

    }

    public class DbCreatenIitializer : DropCreateDatabaseAlways<KeyCoreDbContext>
        // : CreateDatabaseIfNotExists<KeyCoreDbContext>
    {
        protected override void Seed(KeyCoreDbContext context)
        {
            SeedWojewodztwa(context);
            SeedAdresTyp(context);
            SeedKraje(context);
            SeedTypDokumentu(context);
            SeedRoles(context);
            SeedMiejscowosci(context);
            SeedTelefonTyp(context);
            SeedTelefonPrefix(context);

            // nie dodawac tak bo password nie ma salt -> haslo tez nie jest saltowane 
            var newUser = new List<User>
                              {
                                  new User
                                      {
                                          UserName = "Admin",
                                          Password = "123456",
                                          // [Required(AllowEmptyStrings=true)]
                                          PasswordSalt = "",
                                          Email = "admin@test.pl",
                                          CreatedDate = DateTime.Now,
                                          IsApproved = true,
                                          // get local role because roles are fresh added not saved yet 
                                          UserRole = context.UserRoles.Local.Single(n => n.RoleName == "administrator")
                                      }
                              };

            Debug.Print("seeding User Table");
            newUser.ForEach(x => context.Users.Add(x));
            // context.SaveChanges(); no need base.seed save changes
            base.Seed(context);
        }

        private void SeedTelefonPrefix(KeyCoreDbContext context)
        {
            var telefonPrefix = new Dictionary<int, string>
            {
                {48,"Polska"},
                {49,"Niemcy"}
            };

            Debug.Print("seeding TelefonPrefix Table");
            telefonPrefix.ToList().ForEach(k => context.TelefonPrefix.Add(new TelefonPrefix { TelefonPrefixNumer = k.Key, TelefonPrefixKraj = k.Value }));
        }
        private void SeedTelefonTyp(KeyCoreDbContext context)
        {
            var telefontyp = new List<string>
            {
                "stacjonarny","komórkowy"
            };

            Debug.Print("seeding TelefonTyp Table");
            telefontyp.ForEach(typ=>context.TelefonTyp.Add(new TelefonTyp{TelefonTypNazwa = typ}));
        }

        private void SeedMiejscowosci(KeyCoreDbContext context)
        {
            var miejscowosci = new List<string> { "Wrocław","Warszawa","Szczecin" };

            Debug.Print("seeding Miejscowosci Table");
            miejscowosci.ForEach(m => context.Miejscowosc.Add(new Miejscowosc { Nazwa = m }));
        }

        private void SeedTypDokumentu(KeyCoreDbContext context)
        {
            var typDokumentu = new List<string>{
                "dowód osobisty","paszport","prawo jazdy","książeczka wojskowa"
            };

            Debug.Print("seeding TypDokumentu Table");
            typDokumentu.ForEach(typ => context.TypDokumentu.Add(new TypDokumentu{ NazwaDokumentu = typ }));
        }

        private void SeedRoles(KeyCoreDbContext context)
        {
            var newUsersRoles= new List<string>
            {
                "administrator",
                "user"
            };

            Debug.Print("seeding UserRoles Table");
            newUsersRoles.ForEach(role => context.UserRoles.Add(new UserRoles{ RoleName = role}));
        }

        private void SeedKraje(KeyCoreDbContext context)
        {
            var kraje = new List<string>
            {
                "Polska"
            };

            Debug.Print("seeding Kraje Table");
            kraje.ForEach(kraj=>context.Kraj.Add(new Kraj{ Nazwa = kraj}));
        }

        private void SeedAdresTyp(KeyCoreDbContext context)
        {
            var adresTyp = new List<string>
                               {
                                   "zamieszkania",
                                   "zameldowania",
                                   "korespondencyjny"
                               };

            Debug.Print("seeding AdresTyp Table");
            adresTyp.ForEach(typ => context.AdresTyp.Add(new AdresTyp {AdresTypNazwa = typ}));
        }

        private void SeedWojewodztwa(KeyCoreDbContext context)
        {
            var wojewodztwa = new List<string>
                                  {
                                      "dolnośląskie",
                                      "kujawsko-pomorskie",
                                      "lubelskie",
                                      "lubuskie",
                                      "łódzkie",
                                      "małopolskie",
                                      "mazowieckie",
                                      "opolskie",
                                      "podkarpackie",
                                      "podlaskie",
                                      "pomorskie",
                                      "śląskie",
                                      "świętokrzyskie",
                                      "warmińsko-mazurskie",
                                      "wielkopolskie",
                                      "zachodniopomorskie"
                                  };

            Debug.Print("seeding Wojewodztwa Table");
            wojewodztwa.ForEach(w => context.Wojewodztwo.Add(new Wojewodztwo {Nazwa = w}));
        }
    }

    public static class Extension
    {
        public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
        {
            foreach (var item in items) action(item);
        }
    }

}